package plus.easydo.server.file.store.controller;

import com.google.api.client.util.Lists;
import io.minio.ObjectStat;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.java.Log;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import plus.easydo.core.base.controller.BaseController;
import plus.easydo.core.result.R;
import plus.easydo.server.file.store.service.FileManagementService;
import plus.easydo.server.file.store.vo.FileManageVo;
import plus.easydo.starter.file.FileResult;
import plus.easydo.starter.file.FileStoreObject;
import plus.easydo.starter.file.FileStoreUtil;
import plus.easydo.starter.file.minio.MinioTemplate;
import plus.easydo.starter.file.minio.MinioFileStoreServer;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;


/**
 * @author laoyu
 * @version 1.0
 * @date 2021/11/12
 */
@Log
@Api(tags = "存储服务-minio")
@RestController
@RequestMapping("/minio")
public class MinioFileStoreController extends BaseController {


    @Autowired
    MinioFileStoreServer minioFileStoreServer;

    @Autowired
    FileManagementService fileManagementService;


//    @IgnoreThePermissions
    @ApiOperation("文件上传")
    @ResponseBody
    @PostMapping("")
    public R<Object> upload(@RequestParam(name = "file", required = false) MultipartFile file,
                            @RequestParam(name = "fileName", required = false, defaultValue = "") String fileName,
                            @RequestParam(name = "filePath", required = false, defaultValue = "") String filePath,
                            @RequestParam(name = "groupName", required = false, defaultValue = "")String groupName){
        try {
            FileStoreObject<String,MultipartFile> fileStoreObject = new FileStoreObject<>();
            fileStoreObject.setFileName(fileName);
            fileStoreObject.setFilePath(filePath);
            fileStoreObject.setGroupName(groupName);
            fileStoreObject.setIndex(filePath+fileName);
            fileStoreObject.setFile(file);
            R<FileResult<String>> result = minioFileStoreServer.save(fileStoreObject);
            if(result.isSuccess()){
                //持久化文件管理信息
                return ok(fileManagementService.saveFileInfo(result.getData()));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return fail("上传失败");
    }


//    @IgnoreThePermissions
    @ApiOperation("文件下载")
    @GetMapping("/{fileId}")
    public void download(HttpServletResponse response, @PathVariable(name = "fileId") long fileId) {
        InputStream in=null;
        try {
            //获取文件对象 stat原信息
            FileManageVo file = fileManagementService.selectById(fileId);
            MinioTemplate tool = minioFileStoreServer.getTemplate();
            String filePath =  FileStoreUtil.endWithSlash(file.getFilePath());
            String fileName = file.getFileName();
            ObjectStat stat = tool.getObjectInfo(file.getGroupName(), filePath + fileName);
            response.setContentType(stat.contentType());
            response.setContentType("application/octet-stream; charset=UTF-8");
            in = minioFileStoreServer.getFile(file.getGroupName(),file.getFilePath()+file.getFileName());
            IOUtils.copy(in,response.getOutputStream());
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(in!=null){
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    @ApiOperation("文件下载-url")
    @GetMapping("/{groupName}/{filePath}/{fileName}")
    public void download(HttpServletResponse response, @PathVariable(name = "groupName") String groupName,
                         @PathVariable(name = "filePath") String filePath,
                         @PathVariable(name = "fileName") String fileName) {
        InputStream in=null;
        try {
            filePath = FileStoreUtil.endWithSlash(filePath);
            in = minioFileStoreServer.getFile(groupName,filePath + fileName);
            IOUtils.copy(in,response.getOutputStream());
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(in!=null){
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    /**
     * 多上传文件
     *
     * @param files files
     * @param groupName groupName
     * @return java.lang.Object
     * @author laoyu
     * @date 2021/11/14
     */
//    @IgnoreThePermissions
    @ApiOperation(value = "多上传文件")
    @PostMapping("/list")
    public Object uploadList(@ApiParam(name = "files",value = "文件集合参数名称") @RequestParam("files") List<MultipartFile> files,
                             @ApiParam(name = "groupName",value = "分组名")
                             @RequestParam(name = "groupName", required = false, defaultValue = "") String groupName) {
        List<FileResult<String>> resultList = Lists.newArrayList();
        for (MultipartFile file : files) {
            try {
                minioFileStoreServer.getTemplate().createBucket(groupName);
                FileStoreObject<String,MultipartFile> fileStoreObject = new FileStoreObject<>();
                fileStoreObject.setFile(file);
                fileStoreObject.setGroupName(groupName);
                R<FileResult<String>> result = minioFileStoreServer.save(fileStoreObject);
                resultList.add(result.getData());
            } catch (Exception e) {
                e.printStackTrace();
                return fail("文件上传失败");
            }
        }
        return ok(resultList);
    }


}
